﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using MbUnit.Framework;
using Netkk.Common;
using Netkk.Common.Models;
using Netkk.Library.Repositories;
using Netkk.Library.Services;
using Netkk.Library.Validation;
using Rhino.Mocks;

namespace Netkk.Tests.Users
{
    [TestFixture]
    public class MembersTest
    {
        private MockRepository mocks;

        private IUserRepository userRepository;
        private IRoleRepository roleRepository;

        private IUserService userService;
        private IRoleService roleService;

        [SetUp]
        public void Startup()
        {

            loadServices();

        }

        private void loadServices()
        {
            if (userService != null) return;

            ModelStateDictionary modelStateDictionary = new ModelStateDictionary();
            IValidationDictionary validationDictionary = new ModelStateWrapper(modelStateDictionary);

            mocks = new MockRepository();
            userRepository = mocks.StrictMock<IUserRepository>();

            userService = new UserService(validationDictionary, userRepository);
        }

        [TearDown]
        public void Shutdown()
        {
        }

        [Test]
        public void UserService_Sould_Be_Created_Without_A_ModelStateWrapper()
        {
            loadServices();

            IUserService userService = new UserService(null, userRepository);

            mocks.ReplayAll();

            Assert.IsNotNull(userService);

            mocks.VerifyAll();
        }

        [Test]
        public void Selection_Of_All_Valid_Users_Schould_Return_More_Than_One_User()
        {
            loadServices();

            IEnumerable<User> musers = new List<User>()
            {
                new User {Id = Guid.NewGuid(), IsValid = false, AllowShowProfile = false, Role = new Netkk.Common.Models.UserRole { Role = Netkk.Common.Roles.Guest } },
                new User { Id = Guid.NewGuid(), IsValid = true ,AllowShowProfile = false, Role = new Netkk.Common.Models.UserRole { Role = Netkk.Common.Roles.Member } },
                new User { Id = Guid.NewGuid(), IsValid = false, AllowShowProfile = true, Role = new Netkk.Common.Models.UserRole { Role = Netkk.Common.Roles.Member } },
                new User { Id = Guid.NewGuid(), IsValid = true, AllowShowProfile = true , Role = new Netkk.Common.Models.UserRole { Role = Netkk.Common.Roles.Admin } }, 
                new User { Id = Guid.NewGuid(), IsValid = false, AllowShowProfile = true , Role = new Netkk.Common.Models.UserRole { Role = Netkk.Common.Roles.Member } }, 
                new User { Id = Guid.NewGuid(), IsValid = true, AllowShowProfile = true , Role = new Netkk.Common.Models.UserRole { Role = Netkk.Common.Roles.Member } }, 
            };

            Expect.Call(userRepository.Select()).Return(musers);

            mocks.ReplayAll();

            IEnumerable<User> users = userService.ListAllActiveUsers();

            Assert.GreaterThan(users.Count(), 1);

            mocks.VerifyAll();
        }

        [Test]
        public void Selection_Of_All_Users_Schould_Return_More_Than_One_User()
        {
            loadServices();

            IEnumerable<User> musers = new List<User>()
            {
                new User { Id = Guid.NewGuid(), IsValid = false, AllowShowProfile = false},
                new User { Id = Guid.NewGuid(), IsValid = true ,AllowShowProfile = false},
                new User { Id = Guid.NewGuid(), IsValid = false, AllowShowProfile = true},
                new User { Id = Guid.NewGuid(), IsValid = true, AllowShowProfile = true }, 
            };

            Expect.Call(userRepository.Select()).Return(musers);

            mocks.ReplayAll();

            IEnumerable<User> users = userService.ListAllUsers();

            Assert.GreaterThan(users.Count(), 1);

            mocks.VerifyAll();
        }

        [Test]
        [Row("{664d3f17-5031-43ce-8539-caa2e090264e}")]
        [Row("{57eb8f7f-8dd1-40e1-8436-5369805f2cc7}")]
        public void Schould_Return_A_Valid_User_From_A_Given_Id(string guid)
        {
            loadServices();

            Guid id = guid == null ? Guid.NewGuid() : new Guid(guid);

            IEnumerable<User> musers = new List<User>()
            {
                new User { Id = id, IsValid = false, AllowShowProfile = false} 
            };

            Expect.Call(userRepository.Select()).Return(musers);

            mocks.ReplayAll();

            User user = userService.GetUserById(id);

            Assert.IsNotNull(user);

            mocks.VerifyAll();
        }

        [Test]
        [Row("{66777f17-5031-43ce-8539-caa2e090264e}")]
        [Row("{57777f7f-8dd1-40e1-8436-5369805f2cc7}")]
        public void Schould_Not_Return_A_Valid_User_From_A_Given_Id(string guid)
        {
            loadServices();

            Guid id = guid == null ? Guid.NewGuid() : new Guid(guid);

            IEnumerable<User> musers = new List<User>()
            {
                new User { Id = Guid.NewGuid(), IsValid = false, AllowShowProfile = false} 
            };

            Expect.Call(userRepository.Select()).Return(musers);

            mocks.ReplayAll();

            User user = userService.GetUserById(id);

            Assert.IsNull(user);

            mocks.VerifyAll();
        }

        [Test]
        [Row("juergen.gutsch@aspnetzone.de")]
        [Row("peter.bucher@aspnetzone.de")]
        public void Schould_Return_A_Valid_User_From_A_Given_Email(string email)
        {
            loadServices();

            email = email == null ? "juergen.gutsch@contoso.com" : email;

            IEnumerable<User> musers = new List<User>()
            {
                new User { Id = Guid.NewGuid(), Email = email, IsValid = false, AllowShowProfile = false} 
            };

            Expect.Call(userRepository.Select()).Return(musers);

            mocks.ReplayAll();

            User user = userService.GetUserByEmail(email);

            Assert.IsNotNull(user);

            mocks.VerifyAll();
        }

        [Test]
        [Row("juergengutsch@aspnetzone.de")]
        [Row("peterbucher@aspnetzone.de")]
        public void Schould_Not_Return_A_Valid_User_From_A_Given_Email(string email)
        {
            loadServices();

            email = email == null ? "juergen.gutsch@contoso.com" : email;

            IEnumerable<User> musers = new List<User>()
            {
                new User { Id = Guid.NewGuid(), Email = "peter.bucher@contoso.com", IsValid = false, AllowShowProfile = false} 
            };

            Expect.Call(userRepository.Select()).Return(musers);

            mocks.ReplayAll();

            User user = userService.GetUserByEmail(email);

            Assert.IsNull(user);

            mocks.VerifyAll();
        }

        [Test]
        [Row("Juergen", "gucci30")]
        [Row("Peter", "gucci30")]
        public void Schould_Return_A_Valid_User_From_A_Given_Login(string username, string password)
        {
            loadServices();

            username = username == null ? "Juergen" : username;
            password = password == null ? "gucci30" : password;

            IEnumerable<User> musers = new List<User>()
            {
                new User { Name = username, Password = password.ConvertToHash(), IsValid = true} 
            };

            Expect.Call(userRepository.Select()).Return(musers);

            mocks.ReplayAll();

            User users = userService.GetUserByLogin(username, password.ConvertToHash());

            Assert.IsNotNull(users);

            mocks.VerifyAll();
        }

        [Test]
        [Row("Juergen", "gucci20")]
        [Row("Peter", "gucci35")]
        public void Schould_Not_Return_A_Valid_User_From_A_Given_Login(string username, string password)
        {
            loadServices();

            username = username == null ? "Juergen" : username;
            password = password == null ? "gucci30" : password;

            IEnumerable<User> musers = new List<User>()
            {
                new User { Name = "asdasdas", Password = "sdafsdfadf".ConvertToHash(), IsValid = true} 
            };

            Expect.Call(userRepository.Select()).Return(musers);

            mocks.ReplayAll();

            User user = userService.GetUserByLogin(username, password.ConvertToHash());

            Assert.IsNull(user);

            mocks.VerifyAll();
        }

        [Test]
        [Row("Juergen")]
        [Row("Peter")]
        public void Schould_Return_A_Valid_User_From_A_Given_LoginName(string username)
        {
            loadServices();

            username = username == null ? "Juergen" : username;

            IEnumerable<User> musers = new List<User>()
            {
                new User { Name = username, IsValid = true} 
            };

            Expect.Call(userRepository.Select()).Return(musers);

            mocks.ReplayAll();

            User user = userService.GetUserByLoginName(username);

            Assert.IsNotNull(user);

            mocks.VerifyAll();
        }

        [Test]
        [Row("Franz")]
        [Row("Joseph")]
        public void Schould_Not_Return_A_Valid_User_From_A_Given_LoginName(string username)
        {
            loadServices();

            username = username == null ? "Juergen" : username;

            IEnumerable<User> musers = new List<User>()
            {
                new User { Name = "asdfsdfasda", IsValid = true} 
            };

            Expect.Call(userRepository.Select()).Return(musers);

            mocks.ReplayAll();

            User user = userService.GetUserByLoginName(username);

            Assert.IsNull(user);

            mocks.VerifyAll();
        }

        [Test]
        [Row("{664d3f17-5031-43ce-8539-caa2e090264e}")]
        [Row("{57eb8f7f-8dd1-40e1-8436-5369805f2cc7}")]
        public void Schould_Return_A_Validated_User_From_A_Given_Id(string guid)
        {
            loadServices();

            Guid id = guid == null ? Guid.NewGuid() : new Guid(guid);

            IEnumerable<User> musers = new List<User>()
            {
                new User { Id = id, IsValid = true, AllowShowProfile = false} 
            };

            Expect.Call(userRepository.Select()).Return(musers);

            mocks.ReplayAll();

            bool isValid = userService.UserIsValid(id);

            Assert.IsTrue(isValid);

            mocks.VerifyAll();
        }

        [Test]
        [Row("{bf6a2e64-8ef4-7777-9b76-a9406ef06bae}")]
        [Row("{36898160-7777-46af-8d39-63abb41d7bfa}")]
        [Row("{77777777-5604-46af-8d39-a9406ef06bae}")]
        public void Schould_Not_Return_A_Validated_User_From_A_Given_Id(string guid)
        {
            loadServices();

            Guid id = guid == null ? Guid.NewGuid() : new Guid(guid);

            IEnumerable<User> musers = new List<User>()
            {
                new User { Id = Guid.NewGuid(), IsValid = true, AllowShowProfile = false} 
            };

            Expect.Call(userRepository.Select()).Return(musers);

            mocks.ReplayAll();

            bool isValid = userService.UserIsValid(id);

            Assert.IsTrue(!isValid);

            mocks.VerifyAll();
        }

        [Test]
        public void Create_Select_And_Delete_A_User()
        {
            loadServices();

            Guid userId = Guid.NewGuid();
            User user = new User
                        {
                            Id = userId,
                            Name = "Tester",
                            Password = "TopSecret",
                            Email = "Test@Test.com",
                            IsValid = true,
                            Role = new Netkk.Common.Models.UserRole { Role = Netkk.Common.Roles.Member }
                        };


            IEnumerable<User> musers = new List<User>()
            {
                new User { Id = Guid.NewGuid(), Name="Noch Tester", Email="hall@welt.de", IsValid = false, AllowShowProfile = false} 
            };

            Expect.Call(userRepository.Select()).Return(musers).Repeat.Times(3);
            //Expect.Call(userRepository.Save(user));

            mocks.ReplayAll();

            Assert.IsTrue(userService.SaveUser(user), "Benutzer wurde nicht erstellt");

            mocks.VerifyAll();
        }


        //    userService.DeleteUser(user);

        //    user = userService.GetUserById(userId);

        //    Assert.IsNull(user, "Erstellter Benutzer wurde nicht gelöscht");
        //}


    }
}
